package sys.knot.model;

import sys.knot.validator.ValidationException;
import sys.knot.validator.Validator;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class QueryParameter {

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    private String name;
    private ParameterType type;
    private List<Validator> validators = new ArrayList<>();

    public QueryParameter(String name, String typeAsString) {
        this.name = name;
        this.type = ParameterType.valueOf(typeAsString);
    }

    public void setValidators(List<Validator> validators) {
        if (validators != null) {
            this.validators = validators;
        }
    }

    public Object getValidatedParameterFromIndata(Indata indata) {
        Object result = null;
        try {
            String raw = indata.getParameter(name);

            if (raw == null) {
                throw new IllegalArgumentException("Can't find the parameter named " + name +".");
            }
            switch (type) {
                case STRING:
                    result = validate(raw);
                    break;
                case INTEGER:
                    result = validate(Integer.parseInt(raw));
                    break;
                case DATE:
                    result = validate(SIMPLE_DATE_FORMAT.parse(raw));
                    break;
                case STRING_ARRAY:
                    result = validate(raw.split(","));
                    break;
                case NUMBER_ARRAY:
                    String[] rawArray = raw.split(",");
                    int[] temp = new int[rawArray.length];
                    for (int i = 0; i < rawArray.length; i++) {
                        temp[i] = Integer.parseInt(rawArray[i]);
                    }
                    result = validate(temp);
                    break;
            }
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
        return result;
    }


    private String validate(String p) throws ValidationException {
        for (Validator v : validators) {
            v.validate(name, p);
        }
        return p;
    }
    private int validate(int p) throws ValidationException {
        for (Validator v : validators) {
            v.validate(name, p);
        }
        return p;
    }
    private Date validate(Date p) throws ValidationException {
        for (Validator v : validators) {
            v.validate(name, p);
        }
        return p;
    }
    private String[] validate(String[] p) throws ValidationException {
        for (Validator v : validators) {
            v.validate(name, p);
        }
        return p;
    }
    private int[] validate(int[] p) throws ValidationException {
        for (Validator v : validators) {
            v.validate(name, p);
        }
        return p;
    }

    public String getName() {
        return name;
    }

    public ParameterType getType() {
        return type;
    }

    @Override
    public String toString() {
        return type.toString() + ":" + name + "(validators: " + validators + ")";
    }

}
